home *** CD-ROM | disk | FTP | other *** search
/ MacFormat 1995 May / macformat-024.iso / Shareware City / Developers / Kant Pro source Folder / Kant Pro 1.1 ƒ / Shell ƒ / prefs.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-01-19  |  10.9 KB  |  399 lines  |  [TEXT/MMCC]

  1. #include "program globals.h"
  2. #include "prefs.h"
  3. #include "help.h"
  4. #include "dialogs.h"
  5. #include "environment.h"
  6. #include "util.h"
  7. #include "window layer.h"
  8. #include <Folders.h>
  9.  
  10. #define        PREFS_FILE_NAME            "\pKant Generator Pro prefs"
  11. #define        PREFS_TYPE                'pref'
  12. // CREATOR is #defined in "program globals.h"
  13. #define        PREFS_HEADER_VERSION    2
  14.  
  15. Str255            gMyName;
  16. Str255            gMyOrg;
  17.  
  18. typedef struct
  19. {
  20.     long            fileID;
  21.     short            maintopic;
  22.     short            subtopic;
  23.     
  24.     char            regname[40];
  25.     char            regorg[40];
  26.     Boolean            alwaysResolve;
  27.     Boolean            useDefault;
  28.     short            speedDelay;
  29.     FSSpec            moduleFS;
  30. } PrefStruct;
  31.  
  32. /* internal globals for use in prefs.c only */
  33. static long            gFileID;
  34. static Boolean        gCanSavePrefs;
  35. static PrefStruct    thePrefs;
  36. static long            gPrefsFilePos;
  37.  
  38. /*-----------------------------------------------------------------------------------*/
  39. /* internal stuff for prefs.c                                                        */
  40.  
  41. static    enum PrefErrorTypes OpenPrefsFile(short *prefsFileID);
  42. static    enum PrefErrorTypes SetupNewPrefsFile(short prefsFileID);
  43. static    void ClosePrefsFile(short prefsFileID);
  44. static    enum PrefErrorTypes GetNextPrefs(short prefsFileID);
  45. static    enum PrefErrorTypes SavePrefs(short prefsFileID);
  46. static    enum PrefErrorTypes CheckVersion(short prefsFileID);
  47. static    enum PrefErrorTypes GetFileID(void);
  48. static    enum PrefErrorTypes CheckFileID(void);
  49. static    enum PrefErrorTypes Virgin(short prefsFileID);
  50. static    void DefaultPrefs(void);
  51. static    void CopyGlobalsToPrefs(void);
  52. static    void CopyPrefsToGlobals(void);
  53. static    void GetRegistration(void);
  54.  
  55. void SaveThePrefs(void)
  56. /* standard procedure callable from anywhere to save prefs to disk (if possible) */
  57. {
  58.     short            prefsFileID;
  59.     
  60.     if (gCanSavePrefs)        /* if we had no errors in PreferencesInit() */
  61.     {
  62.         OpenPrefsFile(&prefsFileID);    /* open the prefs file */
  63.         CopyGlobalsToPrefs();            /* copy global variables to prefs struct */
  64.         SavePrefs(prefsFileID);            /* save prefs to disk */
  65.         ClosePrefsFile(prefsFileID);    /* close prefs file */
  66.     }
  67. }
  68.  
  69. enum PrefErrorTypes PreferencesInit(void)
  70. {
  71.     short            prefsFileID;
  72.     enum PrefErrorTypes        err;
  73.     
  74.     gCanSavePrefs=FALSE;    /* assume the worst and maybe you'll be pleasantly surprised */
  75.     err=GetFileID();        /* get application file ID */
  76.     if (err!=prefs_allsWell)    /* screwed up already?!? */
  77.         return err;
  78.     
  79.     err=OpenPrefsFile(&prefsFileID);    /* open prefs file (or create new one) */
  80.     if (err!=prefs_allsWell)
  81.     {
  82.         if ((err==prefs_diskReadErr) || (err==prefs_diskWriteErr) || (err==prefs_virginErr))
  83.             ClosePrefsFile(prefsFileID);    /* close & abort if error or if new prefs */
  84.         return err;
  85.     }
  86.     
  87.     err=CheckVersion(prefsFileID);        /* check prefs version */
  88.     if (err!=prefs_allsWell)
  89.     {
  90.         ClosePrefsFile(prefsFileID);
  91.         return err;
  92.     }
  93.     
  94.     GetFPos(prefsFileID, &gPrefsFilePos);
  95.     gPrefsFilePos-=sizeof(thePrefs);
  96.     do
  97.     {
  98.         gPrefsFilePos+=sizeof(thePrefs);
  99.         err=GetNextPrefs(prefsFileID);        /* get prefs struct from file */
  100.         if (err==prefs_noMorePrefsErr)        /* or not */
  101.             return (Virgin(prefsFileID));    /* can't find our file ID, it's our first time */
  102.         
  103.         if (err!=prefs_allsWell)            /* any other error, just abort */
  104.         {
  105.             ClosePrefsFile(prefsFileID);
  106.             return err;
  107.         }
  108.         
  109.         err=CheckFileID();                    /* check file ID of current prefs struct */
  110.     }
  111.     while (err==prefs_IDNotMatchErr);
  112.     
  113.     CopyPrefsToGlobals();                    /* copy prefs struct to program globals */
  114.     ClosePrefsFile(prefsFileID);            /* close prefs file */
  115.     
  116.     return prefs_allsWell;                    /* piece o' cake */
  117. }
  118.  
  119. void PrefsError(enum PrefErrorTypes err)
  120. {
  121.     Str255            tempStr;
  122.     
  123.     switch (err)
  124.     {
  125.         case prefs_diskReadErr:
  126.         case prefs_diskWriteErr:
  127.         case prefs_cantCreatePrefsErr:
  128.         case prefs_cantOpenPrefsErr:
  129.         case prefs_versionNotSupportedErr:
  130.             RemoveHilitePatch();
  131.             DefaultPrefs();                    /* use default prefs if error */
  132.             gCanSavePrefs=FALSE;            /* don't bother trying to save prefs later */
  133.             GetIndString(tempStr, 128, err);    /* get error string from .rsrc file */
  134.             ParamText(tempStr, "\p", "\p", "\p");
  135.             PositionDialog('ALRT', largeAlert);
  136.             StopAlert(largeAlert, 0L);        /* display error alert */
  137.             InstallHilitePatch();
  138.             break;
  139.         default:
  140.             gCanSavePrefs=TRUE;                /* can save prefs to disk later if needed */
  141.             break;
  142.     }
  143. }
  144.  
  145. static    enum PrefErrorTypes OpenPrefsFile(short *prefsFileID)
  146. {
  147.     short            thisFile;
  148.     Boolean            newPrefs;
  149.     unsigned char    *name=PREFS_FILE_NAME;
  150.     OSErr            isHuman;
  151.     short            vRefNum;
  152.     long            dirID;
  153.     FSSpec            prefsFile;
  154.     
  155.     newPrefs=FALSE;
  156.     /* find vRefNum and dirID of preferences folder, creating it if necessary */
  157.     isHuman=FindFolder(kOnSystemDisk, 'pref', kCreateFolder, &vRefNum, &dirID);
  158.     
  159.     if (isHuman!=noErr)        /* screwed up already?!? */
  160.         return prefs_cantOpenPrefsErr;
  161.     
  162.     isHuman=FSMakeFSSpec(vRefNum, dirID, name, &prefsFile);    /* make FSSpec out of it */
  163.     if (isHuman!=noErr)
  164.     {
  165.         if (isHuman==fnfErr)    /* FSSpec is valid, but prefs file does not exist */
  166.         {
  167.             isHuman=FSpCreate(&prefsFile, CREATOR, PREFS_TYPE, 0);    /* so create it */
  168.             if (isHuman!=noErr)                                        /* or not */
  169.                 return prefs_cantCreatePrefsErr;
  170.             newPrefs=TRUE;        /* signal that prefs file is new */
  171.         }
  172.         else return prefs_cantOpenPrefsErr;
  173.     }
  174.     isHuman=FSpOpenDF(&prefsFile, fsRdWrPerm, &thisFile);    /* open prefs file */
  175.     *prefsFileID=thisFile;        /* store file reference number */
  176.     if (isHuman!=noErr)
  177.         return prefs_cantOpenPrefsErr;
  178.     
  179.     if (newPrefs)
  180.         return SetupNewPrefsFile(*prefsFileID);        /* needs initial setup if new */
  181.     
  182.     return prefs_allsWell;
  183. }
  184.  
  185. static    enum PrefErrorTypes SetupNewPrefsFile(short prefsFileID)
  186. /* this writes the prefs version number to the newly created prefs file, so we can
  187.    tell if the prefs file was created by a later version of the program and is
  188.    therefore in a format that we don't support -- forward compatability!  what
  189.    a concept! */
  190. {
  191.     long            count;
  192.     short            temp;
  193.     
  194.     gPrefsFilePos=2L;
  195.     if (SetEOF(prefsFileID, 2L)!=noErr)    /* set length of prefs file to 2 */
  196.         return prefs_diskWriteErr;
  197.     
  198.     SetFPos(prefsFileID, 1, 0L);
  199.     temp=PREFS_HEADER_VERSION;            /* get the prefs version (hardcoded) */
  200.     count=2L;
  201.     if (FSWrite(prefsFileID, &count, &temp)!=noErr)        /* write prefs version */
  202.         return prefs_diskWriteErr;        
  203.     
  204.     return Virgin(prefsFileID);            /* be gentle; it's our first time */
  205. }
  206.  
  207. static    void ClosePrefsFile(short prefsFileID)
  208. {
  209.     FSClose(prefsFileID);                /* close file on disk */
  210.     FlushVol(0L, kOnSystemDisk);        /* flush volume to write out new info */
  211. }
  212.  
  213. static    enum PrefErrorTypes GetNextPrefs(short prefsFileID)
  214. {
  215.     OSErr        isHuman;
  216.     long        count;
  217.     
  218.     count=sizeof(thePrefs);
  219.     isHuman=FSRead(prefsFileID, &count, &thePrefs);        /* get next prefs struct */
  220.     if (isHuman==eofErr)    /* no more left */
  221.         return prefs_noMorePrefsErr;
  222.     if (isHuman!=noErr)        /* some other error */
  223.         return prefs_diskReadErr;
  224.     
  225.     return prefs_allsWell;
  226. }
  227.  
  228. static    enum PrefErrorTypes SavePrefs(short prefsFileID)
  229. {
  230.     long        oldEOF;
  231.     long        count;
  232.     
  233.     GetEOF(prefsFileID, &oldEOF);
  234.     if (gPrefsFilePos>=oldEOF)        /* add new prefs struct onto end of prefs file */
  235.     {
  236.         if (SetEOF(prefsFileID, oldEOF+sizeof(thePrefs))!=noErr)
  237.             return prefs_diskWriteErr;
  238.     }
  239.     
  240.     SetFPos(prefsFileID, 1, gPrefsFilePos);        /* set position inside prefs file */
  241.     count=sizeof(thePrefs);
  242.     /* write prefs struct and return appropriate error code */
  243.     return (FSWrite(prefsFileID, &count, &thePrefs)!=noErr) ?
  244.         prefs_diskWriteErr : prefs_allsWell;
  245. }
  246.  
  247. static    enum PrefErrorTypes CheckVersion(short prefsFileID)
  248. {
  249.     OSErr        isHuman;
  250.     long        count;
  251.     short            temp;
  252.     
  253.     count=2L;
  254.     isHuman=FSRead(prefsFileID, &count, &temp);        /* get prefs version */
  255.     if (isHuman!=noErr)
  256.         return prefs_diskReadErr;
  257.     if (temp>PREFS_HEADER_VERSION)                    /* too new */
  258.         return prefs_versionNotSupportedErr;
  259.     if (temp<PREFS_HEADER_VERSION)                    /* old; overwrite */
  260.         return SetupNewPrefsFile(prefsFileID);
  261.     
  262.     return prefs_allsWell;
  263. }
  264.  
  265. static    enum PrefErrorTypes GetFileID(void)
  266. {
  267.     ParamBlockRec    pb;
  268.     
  269.     pb.fileParam.ioCompletion=0L;
  270.     pb.fileParam.ioNamePtr=LMGetCurApName();
  271.     pb.fileParam.ioVRefNum=0;
  272.     pb.fileParam.ioFVersNum=0;
  273.     pb.fileParam.ioFDirIndex=0;
  274.     if (PBGetFInfo(&pb, FALSE)!=noErr)
  275.         return prefs_diskReadErr;
  276.     
  277.     gFileID=pb.fileParam.ioFlNum;
  278.     
  279.     return prefs_allsWell;
  280. }
  281.  
  282. static    enum PrefErrorTypes CheckFileID(void)
  283. {
  284.     /* compare file ID in current prefs struct to application's file ID */
  285.     return (thePrefs.fileID==gFileID) ? prefs_allsWell : prefs_IDNotMatchErr;
  286. }
  287.  
  288. static    enum PrefErrorTypes Virgin(short prefsFileID)
  289. {
  290.     enum PrefErrorTypes    err;
  291.     
  292.     DefaultPrefs();
  293.     CopyGlobalsToPrefs();
  294.     err=SavePrefs(prefsFileID);
  295.     if (err!=prefs_allsWell)
  296.         return err;
  297.     GetRegistration();
  298.     CopyGlobalsToPrefs();
  299.     err=SavePrefs(prefsFileID);
  300.     
  301.     return (err==prefs_allsWell) ? prefs_virginErr : err;
  302. }
  303.  
  304. static    void DefaultPrefs(void)
  305. {
  306.     unsigned char        *bob="\pBob";
  307.     
  308.     gMainTopicShowing=gSubTopicShowing=0;
  309.     
  310.     Mymemcpy((Ptr)gMyName, (Ptr)bob, bob[0]+1);
  311.     gMyOrg[0]=0x00;
  312.     
  313.     gAlwaysResolve=TRUE;
  314.     gSpeedDelay=0;
  315.     gUseDefault=TRUE;
  316.     gModuleFS.name[0]=0x00;
  317. }
  318.  
  319. static    void CopyGlobalsToPrefs(void)
  320. {
  321.     Mymemset((Ptr)(&thePrefs), 0, sizeof(thePrefs));
  322.     if (gMyName[0]>0x27)
  323.         gMyName[0]=0x27;
  324.     if (gMyOrg[0]>0x27)
  325.         gMyOrg[0]=0x27;
  326.     Mymemcpy((Ptr)thePrefs.regname, (Ptr)gMyName, gMyName[0]+1);
  327.     Mymemcpy((Ptr)thePrefs.regorg, (Ptr)gMyOrg, gMyOrg[0]+1);
  328.     thePrefs.maintopic=gMainTopicShowing;
  329.     thePrefs.subtopic=gSubTopicShowing;
  330.     thePrefs.fileID=gFileID;
  331.     
  332.     thePrefs.alwaysResolve=gAlwaysResolve;
  333.     thePrefs.speedDelay=gSpeedDelay;
  334.     thePrefs.useDefault=gUseDefault;
  335.     thePrefs.moduleFS=gModuleFS;
  336. }
  337.  
  338. static    void CopyPrefsToGlobals(void)
  339. {
  340.     Mymemcpy((Ptr)gMyName, (Ptr)thePrefs.regname, thePrefs.regname[0]+1);
  341.     Mymemcpy((Ptr)gMyOrg, (Ptr)thePrefs.regorg, thePrefs.regorg[0]+1);
  342.     gMainTopicShowing=thePrefs.maintopic;
  343.     gSubTopicShowing=thePrefs.subtopic;
  344.     
  345.     gAlwaysResolve=thePrefs.alwaysResolve;
  346.     gSpeedDelay=thePrefs.speedDelay;
  347.     gUseDefault=thePrefs.useDefault;
  348.     gModuleFS=thePrefs.moduleFS;
  349. }
  350.  
  351. static    void GetRegistration(void)
  352. {
  353.     DialogPtr        theDlog;
  354.     short            itemSelected = 0;
  355.     short            newleft;
  356.     short            newtop;
  357.     short            itemType;
  358.     Handle            item;
  359.     Rect            box;
  360.     ModalFilterUPP    procFilter=NewModalFilterProc(OneButtonFilter);
  361.     UserItemUPP        userUPP=NewUserItemProc(OutlineDefaultButton);
  362.     
  363.     theDlog = GetNewDialog(131, 0L, (WindowPtr)-1L);
  364.     newleft = qd.screenBits.bounds.left + (((qd.screenBits.bounds.right -
  365.                 qd.screenBits.bounds.left) - (theDlog->portRect.right -
  366.                 theDlog->portRect.left)) / 2);
  367.     newtop = qd.screenBits.bounds.top + (((qd.screenBits.bounds.bottom -
  368.                 qd.screenBits.bounds.top) - (theDlog->portRect.bottom -
  369.                 theDlog->portRect.top)) / 2);
  370.     if(newtop < 15)
  371.         newtop = 15;
  372.     GetDItem(theDlog, 1, &itemType, &item, &box);
  373.     InsetRect(&box, -4, -4);
  374.     SetDItem(theDlog, 8, userItem, (Handle)userUPP, &box);
  375.     ParamText(APPLICATION_NAME, "\p", "\p", "\p");
  376.     
  377.     MoveWindow(theDlog, newleft, newtop, TRUE);
  378.     ShowWindow(theDlog);
  379.     while (itemSelected != 1)
  380.     {
  381.         ModalDialog(procFilter, &itemSelected);
  382.     }
  383.     GetDItem(theDlog,4,&itemType,&item,&box);
  384.     GetIText(item,gMyName);
  385.     
  386.     GetDItem(theDlog,5,&itemType,&item,&box);
  387.     GetIText(item,gMyOrg);
  388.  
  389.     if (gMyName[0]==0x00)
  390.         DefaultPrefs();
  391.  
  392.     HideWindow(theDlog);
  393.     DisposeDialog(theDlog);
  394.     DisposeRoutineDescriptor(procFilter);
  395.     DisposeRoutineDescriptor(userUPP);
  396.     
  397.     gIsVirgin=TRUE;
  398. }
  399.